package com.example.leo.mycharmingstudent.a0921;

import android.annotation.TargetApi;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.os.Build;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.example.leo.mycharmingstudent.R;
import com.example.leo.mycharmingstudent.a0905.ToastUtil;

public class WebViewActivity extends AppCompatActivity {

    private static final String TAG = "WebViewActivity";
    public static final String URL = "url";

    //加载网页的控件，只此一家，别无分号
    private WebView mWebView;
    //网页后退一步 按钮
    private Button btnGoBack;
    //网页前进一步 按钮
    private Button btnGoForward;
    //网页后退两步 按钮
    private Button btnBackSteps;
    //网页前进两步 按钮
    private Button btnForwardSteps;
    //网页标题 文本显示框
    private TextView tvWebTile;
    //网页加载进度 进度条
    private ProgressBar pbProgress;
    //使用loadUrl方法调用JS 按钮
    private Button btnLoadUrl;
    //使用evaluateJavaScript方法调用JS 按钮
    private Button btnEvaluate;
    private String mUrl;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view);

        findViews();
        initData();
        initEvent();

    }

    private void findViews() {
        btnGoBack = findViewById(R.id.btn_go_back_activity_web_view);
        btnBackSteps = findViewById(R.id.btn_back_steps_activity_web_view);
        btnGoForward = findViewById(R.id.btn_go_forward_activity_web_view);
        btnForwardSteps = findViewById(R.id.btn_forward_steps_activity_web_view);
        tvWebTile = findViewById(R.id.tv_web_tile_activity_web_view);
        pbProgress = findViewById(R.id.pb_progress_activity_web_view);
        btnLoadUrl = findViewById(R.id.btn_excute_js_loadurl_activity_web_view);
        btnEvaluate = findViewById(R.id.btn_excute_js_evaluate_activity_web_view);
        mWebView = findViewById(R.id.wv_activity_web_view);
    }

    private void initData() {

        Intent intent = getIntent();
        if (intent != null) {
            mUrl = intent.getStringExtra(URL);
        }

        initWebSettings();
        //设置WebViewClient以后，系统认为，
        //你有能力自己处理网页，就不调用系统浏览器了
        mWebView.setWebViewClient(new WebViewClient(){
            /**
             * /@Deprecated注解标识  标识过时了
             * @param view
             * @param url
             * @return
             */
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                Log.e(TAG, "shouldOverrideUrlLoading: "+url);
                return super.shouldOverrideUrlLoading(view, url);
            }

            /**
             * 拦截重定向url
             * @param view
             * @param request
             * @return
             */
            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                Log.e(TAG, "shouldOverrideUrlLoading: "+request.getUrl().toString());
                view.loadUrl(request.getUrl().toString());
                return true;
            }

            /**
             * 页面开始加载时调用
             * 工作当中，会遇到很多拦截url的操作。最好选择onPageStarted方法。
             * @param view
             * @param url
             * @param favicon
             */
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                Log.e(TAG, "onPageStarted: "+url);
            }

            /**
             * 页面开始加载结束时调用
             * @param view
             * @param url
             */
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                Log.e(TAG, "onPageFinished: "+url );
            }

            /**
             * 在加载页面资源时会调用，每一个资源（比如图片）的加载都会调用一次
             * @param view
             * @param url
             */
            @Override
            public void onLoadResource(WebView view, String url) {
                super.onLoadResource(view, url);
//                Log.e(TAG, "onLoadResource: "+url);
            }

            /**
             加载页面的服务器出现错误时（如404）调用。
             App里面使用webview控件的时候遇到了诸如404这类的错误的时候，若也显示浏览器里面的那种错误提示页面就显得很丑陋了
             那么这个时候我们的app就需要加载一个本地的错误提示页面，即webview如何加载一个本地的页面
             步骤1：写一个html文件（error_handle.html），用于出错时展示给用户看的提示页面
             步骤2：将该html文件放置到代码根目录的assets文件夹下
             步骤3：复写WebViewClient的onRecievedError方法
             该方法传回了错误码，根据错误类型可以进行不同的错误分类处理
             值得注意：
             请求远程url网页会请求很多资源，
             如果其中一个不重要的资源访问失败（404），也会回调这个方法
             解决方法：
             如果只是一个远程资源url访问失败，可以设置忽略
             */
            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
//                view.loadUrl("file:///android_asset/error.html");
                Log.e(TAG, "onReceivedError: "+request.getUrl().toString());
            }

            /**
             * 处理https请求,webView默认是不处理https请求的，页面显示空白，需要进行如下设置
             */
            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                super.onReceivedSslError(view, handler, error);
                Log.e(TAG, "onReceivedSslError: " + view.getUrl());
                //等待证书相应，
                // 如果还是无法正常显示页面，将super.onReceivedSslError(view, handler, error);删除
                handler.proceed();
            }
        });

        /*
        注意：
        如果不设置WebChromeClient，网页上的js对话框不显示
         */
        mWebView.setWebChromeClient(new WebChromeClient(){
            /**
             * 获取网页加载进度
             * @param view
             * @param newProgress
             */
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                pbProgress.setProgress(newProgress);
            }

            /**
             * 获取网页标题
             * @param view
             * @param title
             */
            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                tvWebTile.setText(title);
            }

            /**
             * 拦截JS原生对话框，对应的JS方法为alert()
             * @param view
             * @param url
             * @param message
             * @param result
             * @return
             */
            @Override
            public boolean onJsAlert(WebView view,
                                     String url,
                                     String message,
                                     final JsResult result) {
                new AlertDialog.Builder(WebViewActivity.this)
                        .setTitle("JSAlert")
                        .setMessage(message)
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.confirm();
                            }
                        })
                        .setCancelable(false)
                        .show();
                //返回true，表示使用Android原生对话框，替换JS原生对话框
                //返回true，表示自己处理
                return true;
            }

            /**
             * 拦截JS原生对话框，对应的JS方法confirm()
             * @param view
             * @param url
             * @param message
             * @param result
             * @return
             */
            @Override
            public boolean onJsConfirm(WebView view,
                                       String url,
                                       String message,
                                       final JsResult result) {
                new AlertDialog.Builder(WebViewActivity.this)
                        .setTitle("JsConfirm")
                        .setMessage(message)
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.confirm();
                            }
                        })
                        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.cancel();
                            }
                        })
                        .setCancelable(false)
                        .show();
                return true;
            }

            /**
             * 拦截JS原生对话框，对应的JS方法prompt()
             * @param view
             * @param url
             * @param message
             * @param defaultValue
             * @param result
             * @return
             */
            @Override
            public boolean onJsPrompt(WebView view,
                                      String url,
                                      String message,
                                      String defaultValue,
                                      final JsPromptResult result) {
                final EditText et = new EditText(WebViewActivity.this);
                et.setText(defaultValue);
                new AlertDialog.Builder(WebViewActivity.this)
                        .setTitle(message)
                        .setView(et)
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.confirm(et.getText().toString());
                            }
                        })
                        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.cancel();
                            }
                        })
                        .setCancelable(false)
                        .show();
                return true;
            }
        });

        mWebView.addJavascriptInterface(new JavaInterface(), "android");
    }

    /**
     * 专门初始化wensettings设置
     */
    private void initWebSettings() {
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        //设置自适应屏幕，两者合用
        //将图片调整到适合webview的大小
        webSettings.setUseWideViewPort(true);
        //缩放至屏幕的大小
        webSettings.setLoadWithOverviewMode(true);

        //支持缩放，默认为true。是下面那个的前提。
        webSettings.setSupportZoom(true);
        //内置缩放控件,ture,WebView可缩放;false不可缩放,并且下面的方法无效
        webSettings.setBuiltInZoomControls(true);
        //false隐藏，true显示原生的缩放控件
        webSettings.setDisplayZoomControls(true);

        /*
        Build.VERSION.SDK_INT获取当前系统的SDK版本
        Build.VERSION_CODES.LOLLIPOP API级别21
         */
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            //混用http和https
            webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
    }

    private void initEvent() {
//        mWebView.loadUrl("http://www.baidu.com");
//        mWebView.loadUrl("file:///android_asset/index.html");
//        mWebView.loadUrl("https://www.wanandroid.com/");
        if (TextUtils.isEmpty(mUrl)) {
            mWebView.loadUrl("file:///android_asset/index.html");
        } else {
            //mUrl != null && !mUrl.equals("")  等同于else中的判断
            mWebView.loadUrl(mUrl);
        }

        btnGoBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //判断是否可以回退一步，可以则回退，不可以则提示
                if (mWebView.canGoBack()) {
                    //可以回退上一个网页
                    mWebView.goBack();
                } else {
                    //不可以回退上一个网页
                    ToastUtil.showToast(WebViewActivity.this, "坚决不后退");
                }
            }
        });

        btnGoForward.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //判断是否可以前进一步，可以则前进，不可以则提示
                if (mWebView.canGoForward()) {
                    //可以前进到下一个网页
                    mWebView.goForward();
                } else {
                    //不可以前进到下一个网页
                    ToastUtil.showToast(WebViewActivity.this, "前方悬崖，及时勒马");
                }
            }
        });

        btnBackSteps.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //判断网页能否后退两步，能则后退，不能则提示
                /*
                canGoBackOrForward steps为负数则为后退，正数则为前进
                 */
                if (mWebView.canGoBackOrForward(-2)) {
                    //能后退两步，后退两步
                    mWebView.goBackOrForward(-2);
                } else {
                    //不能后退两步，提示
                    ToastUtil.showToast(WebViewActivity.this, "坚决不后退两步");
                }
            }
        });

        btnForwardSteps.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //判断网页能否前进两步，能则前进，不能则提示
                /*
                canGoBackOrForward steps为负数则为后退，正数则为前进
                 */
                if (mWebView.canGoBackOrForward(2)) {
                    //能前进两步，前进两步
                    mWebView.goBackOrForward(2);
                } else {
                    //不能前进两步，提示
                    ToastUtil.showToast(WebViewActivity.this,
                            "前方两步是悬崖，及时勒马");
                }
            }
        });

        btnLoadUrl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //使用loadUrl方法调用JS
                //不可接受js方法的返回值
                mWebView.loadUrl("javascript:AndroidCallJs1()");
            }
        });

        btnEvaluate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //使用evaluateJavaScript方法调用JS
                //可接收js方法的返回值
                mWebView.evaluateJavascript("javascript:AndroidCallJs2(1,2)", new ValueCallback<String>() {
                    @Override
                    public void onReceiveValue(String value) {
                        ToastUtil.showToast(WebViewActivity.this, value);
                    }
                });
            }
        });
    }

    /**
     * 监听按键落下的事件回调方法
     * 作用：监听按下的按键
     * @param keyCode
     * @param event
     * @return
     */
    /*@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        *//*
        每个按键都对应这一个按键码，系统定义好的

        KeyEvent.KEYCODE_BACK表示返回键
        keyCode == KeyEvent.KEYCODE_BACK表示 判断当前的按键是否为返回键
         *//*
        if(keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()){
            mWebView.goBack();
            return true;
        }

        *//*
        劫持返回按键，不让Activity关闭
         *//*
        *//*if(keyCode == KeyEvent.KEYCODE_BACK){
            if (mWebView.canGoBack()) {
                mWebView.goBack();
            }
            return true;
        }*//*
        return super.onKeyDown(keyCode, event);
    }*/

    /**
     * 上次点击返回按钮的时间
     */
    private long mClickBackTimeMillis = 0;

    /**
     * 只监听返回按键
     */
    @Override
    public void onBackPressed() {
        if (mWebView.canGoBack()) {
            mWebView.goBack();
        }else {
            /*
            两次点击返回键退出app功能
            1.时间段  比如两秒、三秒
            2.时间戳的记录  当前点击返回按键的时间戳，上一次点击返回按键的时间戳
            注意：不是每个Activity都要加，主页Activity可以添加这个功能
             */
            //本次点击返回按钮的时间
            long currentTimeMillis = System.currentTimeMillis();
            if (currentTimeMillis - mClickBackTimeMillis < 2000) {
                //super.方法名  表示调用父类的此方法
                super.onBackPressed();
            } else {
                //将本次点击返回按钮的时间，赋值给上次点击返回按钮的时间
                mClickBackTimeMillis = currentTimeMillis;
                ToastUtil.showToast(this,"再次点击退出");
            }
        }
//        super.onBackPressed();
    }

    /**
     * Activity最后一个生命周期
     * 可以用来释放资源（执行时间短的）
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        /*
        注意：实际开发中，不一定每一个方法都要执行
        主要目的：讲明白webview清除数据在哪里执行
         */
        //清除缓存数据
        mWebView.clearCache(true);
        //清除历史记录
        mWebView.clearHistory();
        //清除表单数据
        mWebView.clearFormData();
    }

    public class JavaInterface{

        @JavascriptInterface
        public String showToast(String msg){
            ToastUtil.showToast(WebViewActivity.this, msg);
            return "JS调用了Android原生代码";
        }

    }
}
